package com.gaodun.scrm.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.gaodun.scrm.common.result.Result;
import com.gaodun.scrm.common.result.ResultCodeEnum;
import org.apache.http.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URLDecoder;
import java.util.List;

/*本全局过滤器仅供实际业务参考，提供了常用的过滤方法*/
@Component
public class AuthGlobalFilter implements GlobalFilter {

    @Autowired
    private RedisTemplate redisTemplate;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    //可以在配置文件中配置白名单或黑名单
    @Value("${authUrls.url}")
    private String authUrls;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String path = request.getURI().getPath();
        System.out.println(path);

        //内部
        if(antPathMatcher.match("/**/inner/**", path)){
            return out(response, ResultCodeEnum.PERMISSION);
        }

        String userId = getUserId(request);

        //axios发起的ajax请求，重定向交给前端实现
        if(antPathMatcher.match("/api/**/auth/**", path)){
            if(StringUtils.isEmpty(userId)){
                return out(response, ResultCodeEnum.LOGIN_AUTH);
            }
        }

        //其他的需要拦截的“html页面”请求，同步页面重定向由后端实现
        for (String url : authUrls.split(",")) {
            if(path.indexOf(url) != -1 && StringUtils.isEmpty(userId)){
                response.setStatusCode(HttpStatus.SEE_OTHER);
                response.getHeaders().set(HttpHeaders.LOCATION, "http://luffy.gaodunwangxiao.com/login.html?originUrl="
                        + request.getURI().getRawSchemeSpecificPart());
                return response.setComplete();
            }
        }

        //更改请求头主要是考虑到同步请求数据是从cookie来的，header为空
        if(!StringUtils.isEmpty(userId)){
            //换一个新请求，并把原请求的内容转移到新请求
            //用于改变长连接过程中，想要修改请求头的情况，必须关掉当前连接，新开一个请求
            request.mutate().header("userId", userId);
        }

        String userTempId = this.getUserTempId(request);
        if(!StringUtils.isEmpty(userTempId)){
            request.mutate().header("userTempId",userTempId);
        }

        return chain.filter(exchange);

    }

    private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {

        Result<Object> result = Result.build(null, resultCodeEnum);
        byte[] bytes = JSON.toJSONString(result).getBytes();
        DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
        response.getHeaders().set(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf-8");
        return response.writeWith(Mono.just(dataBuffer));
    }

    private String getUserId(ServerHttpRequest request) {

        String token = request.getHeaders().getFirst("token");
        if(StringUtils.isEmpty(token)){
            HttpCookie httpCookie = request.getCookies().getFirst("token");
            if(httpCookie != null){
                token = httpCookie.getValue();
            }
        }

        if(!StringUtils.isEmpty(token)){
            if(redisTemplate.hasKey( "user:login:" + token)){
                return (String) redisTemplate.opsForValue().get("user:login:" + token);
            }
        }

        return null;
    }

    /**
     * 获取当前用户临时用户id
     * @param request
     * @return
     */
    private String getUserTempId(ServerHttpRequest request){
        String userTempId = "";
        List<String> tokenList = request.getHeaders().get("userTempId");
        if(null != tokenList){
            userTempId = tokenList.get(0);
        }else {
            MultiValueMap<String, HttpCookie> cookieMultiValueMap = request.getCookies();
            HttpCookie cookie = cookieMultiValueMap.getFirst("userTempId");
            if(null != cookie){
                userTempId = URLDecoder.decode(cookie.getValue());
            }
        }
        return userTempId;
    }

}
